﻿#include "PickedDataCalculator.h"
#include "PickedData.h"

#include "GraphDataVTKAdaptor/GraphVTKCommons.h"
#include "GraphDataVTKAdaptor/GraphVTKObject3D.h"
#include "GraphDataVTKAdaptor/GraphVTKObjectPartMesh.h"


#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKKeyMouseStates.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"
#include "FITK_Kernel/FITKCore/FITKVec3D.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKShellFeatureEdges.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKSurfaceFilter.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKExtractGeometry.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKGraphActor.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKPolyDataTool.h"

#include "FITK_Interface/FITKInterfaceMesh/FITKMeshFeatureVTK.h"
#include "FITK_Component/FITKRadiossData/FITKRadiossCase.h"
#include "FITK_Component/FITKRadiossData/FITKRadiossMeshModel.h"
#include "FITK_Component/FITKRadiossData/FITKRadiossNodesParts.h"
#include <vtkActor.h>
#include <vtkMapper.h>
#include <vtkPlanes.h>
#include <vtkUnstructuredGrid.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkDataSet.h>
namespace GraphData
{
    PickedDataCalculator::PickedDataCalculator(GraphData::PickedData* pickedData) :
        m_pickedData(pickedData)
    {

    }

    void PickedDataCalculator::calculate()
    {
        if (!m_pickedData)
        {
            return;
        }

        //点选拾取方式
        if (m_pickedData->getPickedMouseType() == PickedMouseType::PickedMouseClick) {
            // 获取拾取时的方式。
            GUI::GUIPickInfoStru pickInfo = m_pickedData->getPickedInfo();
            switch (pickInfo._pickMethod) {
            case GUI::GUIPickInfo::PickMethod::PMIndividually:
            case GUI::GUIPickInfo::PickMethod::PMSingle: {
                Individually();
                break;
            }
            case GUI::GUIPickInfo::PickMethod::PMByAngle: {
                // 处理角度算法拾取
                ByAngle();
                break;
            }
            default: return;
            }
        }
        //框选拾取方式
        else if (m_pickedData->getPickedMouseType() == PickedMouseType::PickedMouseRubber)
        {
            byAreaPick();
        }

        // 不管计算完成都将是否需要计算标识置为false。
        m_pickedData->calculateFinsish();
    }

    void PickedDataCalculator::Individually()
    {
        Exchange::GraphVTKObject3D* gobj = m_pickedData->getPickedGraphObejct();
        int index = m_pickedData->getPickedIndex();
        if (gobj == nullptr || index < 0) {
            return;
        }

        int id = -1;
        int vTopoIndex = -1;
        // 根据拾取数据类型进行不同数据获取。
        switch (m_pickedData->getPickedDataType()) {
        case GUI::GUIPickInfo::PickObjType::POBGeoVert:
            //查找几何点
            id = gobj->getShapeIdByVTKCellId(index, Exchange::GraphVTKCommons::ShapePickMode::PickGeoVertex);
            vTopoIndex = gobj->getVirTopoIndexByShapeId(id, Exchange::GraphVTKCommons::ShapePickMode::PickGeoVertex);
            m_pickedData->addPickOtherInfo(PickDataInfo(id));
            m_pickedData->appendPickedOtherId(id, vTopoIndex);
            break;
        case GUI::GUIPickInfo::PickObjType::POBGeoEdge:
            //查找几何线
            id = gobj->getShapeIdByVTKCellId(index, Exchange::GraphVTKCommons::ShapePickMode::PickGeoEdge);
            vTopoIndex = gobj->getVirTopoIndexByShapeId(id, Exchange::GraphVTKCommons::ShapePickMode::PickGeoEdge);
            m_pickedData->addPickOtherInfo(PickDataInfo(id));
            m_pickedData->appendPickedOtherId(id, vTopoIndex);
            break;
        case GUI::GUIPickInfo::PickObjType::POBGeoFace:
            //查找几何面
            id = gobj->getShapeIdByVTKCellId(index, Exchange::GraphVTKCommons::ShapePickMode::PickGeoFace);
            vTopoIndex = gobj->getVirTopoIndexByShapeId(id, Exchange::GraphVTKCommons::ShapePickMode::PickGeoFace);
            m_pickedData->addPickOtherInfo(PickDataInfo(id));
            m_pickedData->appendPickedOtherId(id, vTopoIndex);
            break;
        case GUI::GUIPickInfo::PickObjType::POBGeoSolid:
            //查找几何体
            id = gobj->getShapeIdByVTKCellId(index, Exchange::GraphVTKCommons::ShapePickMode::PickGeoSolid);
            vTopoIndex = gobj->getVirTopoIndexByShapeId(id, Exchange::GraphVTKCommons::ShapePickMode::PickGeoSolid);
            m_pickedData->addPickOtherInfo(PickDataInfo(id));
            m_pickedData->appendPickedOtherId(id, vTopoIndex);
            break;
        case GUI::GUIPickInfo::PickObjType::POBMeshVert:
            //查找网格点
            id = gobj->getShapeIdByVTKCellId(index, Exchange::GraphVTKCommons::ShapePickMode::PickMeshVertex);
            m_pickedData->addPickOtherInfo(PickDataInfo(id));
            break;
        case GUI::GUIPickInfo::PickObjType::POBMeshVertSurf:
            //查找网格单元
            id = gobj->getShapeIdByVTKCellId(index, Exchange::GraphVTKCommons::ShapePickMode::PickMeshVertexSurf);
            m_pickedData->addPickOtherInfo(PickDataInfo(id));
            break;
        case GUI::GUIPickInfo::PickObjType::POBMeshCell:
            //查找网格单元
            id = gobj->getShapeIdByVTKCellId(index, Exchange::GraphVTKCommons::ShapePickMode::PickMeshCell);
            m_pickedData->addPickOtherInfo(PickDataInfo(id));
            break;
        case GUI::GUIPickInfo::PickObjType::POBMeshCellSurf:
            IndividuallyByMeshCellSurf();
            break;
        default:
            break;
        }
    }

    void PickedDataCalculator::IndividuallyByMeshCellSurf()
    {
        if (m_pickedData == nullptr) return;
        //获取GraphVTKObjectPartMesh
        Exchange::GraphVTKObjectPartMesh* partMeshObj = dynamic_cast<Exchange::GraphVTKObjectPartMesh*>(m_pickedData->getPickedGraphObejct());
        if (partMeshObj == nullptr) return;
        int index = m_pickedData->getPickedIndex();
        if (partMeshObj == nullptr || index < 0) return;
        //查找原始FITK单元id与表面索引
        int cellID = partMeshObj->getShapeIdByVTKCellId(index, Exchange::GraphVTKCommons::ShapePickMode::PickMeshCellSurf);
        int cellSurfIndex = partMeshObj->getEleSurfIndexByEleSurfCellID(index, Exchange::GraphVTKCommons::ShapePickMode::PickMeshCellSurf);

        PickDataInfo otherInfo;
        otherInfo._id = cellID;
        otherInfo._otherInfo.append(cellSurfIndex);
        m_pickedData->addPickOtherInfo(otherInfo);

        Interface::FITKMeshFeatureVTK* meshFeature = partMeshObj->getMeshFeature();
        if (meshFeature == nullptr) return;
        //获取表面提取过滤器
        FITKSurfaceFilter* surfaceFilter = meshFeature->getSurfaceFilter();
        int orgCellIndex = -1;
        int faceIndex = -1;
        surfaceFilter->getSurfaceCellInfo(m_pickedData->getPickedIndex(), orgCellIndex, faceIndex);
        vtkDataSet* partGrid = partMeshObj->getMesh(Exchange::GraphVTKCommons::ShapePickMode::PickMeshCell);
        QList<int> face;
        vtkCell* fullCell = partGrid->GetCell(orgCellIndex);
        vtkCell* faceCell = fullCell->GetFace(faceIndex);
        vtkIdList* cellPoints{ nullptr };
        if (faceCell)
        {
            cellPoints = faceCell->GetPointIds();
        }
        else {
            cellPoints = fullCell->GetPointIds();
        }

        if (cellPoints == nullptr) return;

        // 获取节点ID数组 - 用于将VTK节点索引转换为实际节点ID
        vtkIntArray* nodeIdArray = vtkIntArray::SafeDownCast(
            partGrid->GetPointData()->GetArray(Exchange::GraphVTKCommons::_dataCellIDArratName.toUtf8().constData()));
        Radioss::FITKRadiossCase* caseData = FITKAPP->getGlobalData()->getPhysicsData<Radioss::FITKRadiossCase>();
        if (caseData == nullptr) return;
        Radioss::FITKRadiossMeshModel* meshModel = caseData->getMeshModel();
        if (meshModel == nullptr) return;
        Radioss::FITKRadiossNodes* radiossNodes = meshModel->getNodes();
        if (radiossNodes == nullptr) return;

        for (int i = 0; i < cellPoints->GetNumberOfIds(); i++)
        {
            int ptIndex = cellPoints->GetId(i);
            int ptId = -1;
            // 通过全局节点管理器获取
            if (radiossNodes != nullptr && ptIndex >= 0 && ptIndex < radiossNodes->getNodeCount()) {
                Core::FITKNode* node = radiossNodes->getNodeAt(ptIndex);
                if (node != nullptr) {
                    ptId = node->getNodeID();
                }
            }

            if (ptId == -1)
            {
                face.clear();
                break;
            }
            else
            {
                face.push_back(ptId);
            }
        }

        if (!face.isEmpty())
        {
            m_pickedData->FaceMap[cellID].push_back(face);
            m_pickedData->FaceMapInternal[cellID].push_back(faceIndex);
        }

        if (cellID == -1) return;
        m_pickedData->Ids.push_back(cellID);
    }
    void PickedDataCalculator::ByAngle()
    {
        if (m_pickedData == nullptr) return;
        switch (m_pickedData->getPickedDataType())
        {
        case GUI::GUIPickInfo::POBMeshVert:
            ByAngleMeshPoint();
            break;
        case GUI::GUIPickInfo::POBMeshVertSurf:
        {
            ByAngleMeshSurfPoint();
            break;
        }
        case GUI::GUIPickInfo::POBMeshCell:
        {
            ByAngleMeshCell();
            break;
        }
        case GUI::GUIPickInfo::POBMeshCellSurf:
        {
            ByAngleMeshCellSurf();
            break;
        }
        }
    }
    void PickedDataCalculator::ByAngleMeshPoint()
    {
        if (m_pickedData == nullptr) return;
        //获取GraphVTKObjectPartMesh
        Exchange::GraphVTKObjectPartMesh* partMeshObj = dynamic_cast<Exchange::GraphVTKObjectPartMesh*>(m_pickedData->getPickedGraphObejct());
        if (partMeshObj == nullptr) return;
        //获取当前被拾取的Part
        Radioss::FITKRadiossPart* part = FITKDATAREPO->getTDataByID<Radioss::FITKRadiossPart>(m_pickedData->getPickedDataObjId());
        if (part == nullptr) return;

        //获取网格特征
        Interface::FITKMeshFeatureVTK* meshFeature = partMeshObj->getMeshFeature();
        if (meshFeature == nullptr) return;
        //获取表面提取器
        FITKSurfaceFilter* surfaceFilter = meshFeature->getSurfaceFilter();
        if (surfaceFilter == nullptr) return;

        // 查找对应的表面点
        int surfId = -1;
        for (int i = 0; i < surfaceFilter->GetOutput()->GetNumberOfPoints(); i++) {
            if (m_pickedData->getPickedIndex() == surfaceFilter->getOriginPointIdBySurfacePointId(i)) {
                surfId = i;
                break;
            }
        }
        
        if (surfId == -1) {
            return;
        }
        
        //获取表面特征数据与法向数据
        vtkPolyData* surfacePoly = meshFeature->getFeatureMesh(1);
        vtkDataArray* normals = meshFeature->getCellNormals();
        Common::FITKPolyDataTool tool(surfacePoly, normals);

        //根据拾取单元id与拾取角度，获取面id
        QList<int> surfPointIds = tool.getCoPlanePointIDs(surfId, m_pickedData->getPickedInfo()._pickParam);
        QList<int> pointIds = part->getAllNodeIDs();
        
        for (int& surfPoint : surfPointIds) {
            //当前表面节点VTKid对应的真实节点的全局索引
            int realGlobalIndex = surfaceFilter->getOriginPointIdBySurfacePointId(surfPoint);
            int nodeId = pointIds.at(realGlobalIndex);
            m_pickedData->addPickOtherInfo(PickDataInfo(nodeId));
        }
    }

    void PickedDataCalculator::ByAngleMeshSurfPoint()
    {
        if (m_pickedData == nullptr) return;
        Exchange::GraphVTKObjectPartMesh* partMeshObj = dynamic_cast<Exchange::GraphVTKObjectPartMesh*>(m_pickedData->getPickedGraphObejct());
        if (partMeshObj == nullptr) return;
        //获取当前被拾取的Part
        Radioss::FITKRadiossPart* part = FITKDATAREPO->getTDataByID<Radioss::FITKRadiossPart>(m_pickedData->getPickedDataObjId());
        if (part == nullptr) return;

        Interface::FITKMeshFeatureVTK* meshFeature = partMeshObj->getMeshFeature();
        if (meshFeature == nullptr) return;

        FITKSurfaceFilter* surfaceFilter = meshFeature->getSurfaceFilter();
        if (surfaceFilter == nullptr) return;

        //获取表面特征数据与法向数据
        vtkPolyData* surfacePoly = meshFeature->getFeatureMesh(1);
        vtkDataArray* normals = meshFeature->getCellNormals();
        Common::FITKPolyDataTool tool(surfacePoly, normals);

        // 根据拾取单元id与拾取角度，获取共面点id
        QList<int> surfPointIds = tool.getCoPlanePointIDs(m_pickedData->getPickedIndex(), m_pickedData->getPickedInfo()._pickParam);
        for (int& surfPointId : surfPointIds) {
            QList<int> pointIds = part->getAllNodeIDs();
            // 当前表面节点VTKid对应的真实节点的VTKid
            int realId = surfaceFilter->getOriginPointIdBySurfacePointId(surfPointId);
            int nodeId = pointIds.at(realId);
            m_pickedData->addPickOtherInfo(PickDataInfo(nodeId));
        }
    }

    void PickedDataCalculator::ByAngleMeshCell()
    {
        if (m_pickedData == nullptr) return;
        //获取拾取的GraphVTKObjectPartMesh类型
        Exchange::GraphVTKObjectPartMesh* partMeshObj = dynamic_cast<Exchange::GraphVTKObjectPartMesh*>(m_pickedData->getPickedGraphObejct());
        if (partMeshObj == nullptr) return;

        Radioss::FITKRadiossPart* part = FITKDATAREPO->getTDataByID<Radioss::FITKRadiossPart>(m_pickedData->getPickedDataObjId());
        if (part == nullptr) return;
        //获取网格特征
        Interface::FITKMeshFeatureVTK* meshFeature = partMeshObj->getMeshFeature();
        if (meshFeature == nullptr) return;

        FITKSurfaceFilter* surfaceFilter = meshFeature->getSurfaceFilter();
        if (surfaceFilter == nullptr) return;
        //获取到的单元id（网格单元VTKid）在表面提取后表面上对应的VTKid
        int surfId = -1;
        for (int i = 0; i < surfaceFilter->GetOutput()->GetNumberOfCells(); i++) {
            if (m_pickedData->getPickedIndex() == surfaceFilter->getOriginCellIdBySurfaceCellId(i)) {
                surfId = i;
                break;
            }
        }
        //如果surfid不在，则该是去不在表面上
        if (surfId == -1) {
            return;
        }
        //获取表面特征数据与法向数据
        vtkPolyData* surfacePoly = meshFeature->getFeatureMesh(1);
        vtkDataArray* normals = meshFeature->getCellNormals();
        Common::FITKPolyDataTool tool(surfacePoly, normals);

        //根据拾取单元id与拾取角度，获取面id
        QList<int> surfCellIds = tool.getCoPlaneCellIDs(surfId, m_pickedData->getPickedInfo()._pickParam);
        for (int& surfCell : surfCellIds)
        {
            //当前表面单元VTKid对应的真实单元的VTKid
            int realId = surfaceFilter->getOriginCellIdBySurfaceCellId(surfCell);
            //根据真实单元的id获取数据结构单元id
            int id = part->getEleIDByIndex(realId);
            m_pickedData->addPickOtherInfo(PickDataInfo(id));
        }
    }
    void PickedDataCalculator::ByAngleMeshCellSurf()
    {
        if (m_pickedData == nullptr) return;
        // 获取GraphVTKObjectPartMesh
        Exchange::GraphVTKObjectPartMesh* partMeshObj = dynamic_cast<Exchange::GraphVTKObjectPartMesh*>(m_pickedData->getPickedGraphObejct());
        if (partMeshObj == nullptr) return;

        Radioss::FITKRadiossPart* part = FITKDATAREPO->getTDataByID<Radioss::FITKRadiossPart>(m_pickedData->getPickedDataObjId());
        if (part == nullptr) return;

        vtkDataSet* partGrid = partMeshObj->getMesh(Exchange::GraphVTKCommons::ShapePickMode::PickMeshCell);
        if (partGrid == nullptr) return;

        Interface::FITKMeshFeatureVTK* meshFeature = partMeshObj->getMeshFeature();
        if (meshFeature == nullptr) return;

        FITKSurfaceFilter* surfaceFilter = meshFeature->getSurfaceFilter();
        if (surfaceFilter == nullptr) return;
        // 获取表面特征数据与法向数据
        vtkPolyData* surfacePoly = meshFeature->getFeatureMesh(1);
        vtkDataArray* normals = meshFeature->getCellNormals();
        if (surfacePoly == nullptr || normals == nullptr) return;
        Common::FITKPolyDataTool tool(surfacePoly, normals);
        // 获取全局节点数据用于节点ID转换
        Radioss::FITKRadiossCase* caseData = FITKAPP->getGlobalData()->getPhysicsData<Radioss::FITKRadiossCase>();
        if (caseData == nullptr) return;

        Radioss::FITKRadiossMeshModel* meshModel = caseData->getMeshModel();
        if (meshModel == nullptr) return;

        Radioss::FITKRadiossNodes* radiossNodes = meshModel->getNodes();
        if (radiossNodes == nullptr) return;
        // 根据拾取单元id与拾取角度，获取共面的表面单元id
        QList<int> surfCellIds = tool.getCoPlaneCellIDs(m_pickedData->getPickedIndex(), m_pickedData->getPickedInfo()._pickParam);
        for (int& surfCellId : surfCellIds) {
            // 表面单元在实际单元中的面索引
            int faceIndex = -1;
            // 当前表面单元VTKid对应的真实单元VTKid
            int realVTKCellId = -1;
            surfaceFilter->getSurfaceCellInfo(surfCellId, realVTKCellId, faceIndex);

            // 根据真实单元VTKid获取数据结构单元id
            int eleId = part->getEleIDByIndex(realVTKCellId);
            if (eleId == -1) continue;

            // 添加到拾取ID列表
            m_pickedData->Ids.push_back(eleId);

            if (faceIndex != -1) {
                QList<int> face;
                vtkCell* fullCell = partGrid->GetCell(realVTKCellId);
                if (fullCell == nullptr) continue;

                vtkCell* faceCell = fullCell->GetFace(faceIndex);
                vtkIdList* cellPoints = nullptr;

                if (faceCell) {
                    cellPoints = faceCell->GetPointIds();
                }
                else {
                    cellPoints = fullCell->GetPointIds();
                }

                if (cellPoints == nullptr) continue;

                // 获取面上的所有节点ID
                for (int i = 0; i < cellPoints->GetNumberOfIds(); i++) {
                    int ptIndex = cellPoints->GetId(i);
                    int ptId = -1;

                    // 通过全局节点管理器获取节点ID
                    if (ptIndex >= 0 && ptIndex < radiossNodes->getNodeCount()) {
                        Core::FITKNode* node = radiossNodes->getNodeAt(ptIndex);
                        if (node != nullptr) {
                            ptId = node->getNodeID();
                        }
                    }

                    if (ptId == -1) {
                        face.clear();
                        break;
                    }
                    else {
                        face.push_back(ptId);
                    }
                }

                // 如果成功获取所有面节点，保存面信息
                if (!face.isEmpty()) {
                    m_pickedData->FaceMap[eleId].push_back(face);
                    m_pickedData->FaceMapInternal[eleId].push_back(faceIndex);
                }
            }

            // 添加拾取额外参数
            PickDataInfo otherInfo;
            otherInfo._id = eleId;
            otherInfo._otherInfo.append(faceIndex);
            m_pickedData->addPickOtherInfo(otherInfo);
        }
    }
    void PickedDataCalculator::byAreaPick()
    {
        Exchange::GraphVTKObject3D* gobj = m_pickedData->getPickedGraphObejct();
        vtkPlanes* planes = m_pickedData->getCutPlane();
        vtkActor* actor = m_pickedData->getPickedActor();
        if (!gobj || !planes || !actor)
        {
            return;
        }

        // 获取拾取数据集。
        vtkDataSet* dataSet = actor->GetMapper()->GetInputAsDataSet();
        if (!dataSet)
        {
            return;
        }

        vtkSmartPointer<FITKExtractGeometry> extractor = vtkSmartPointer<FITKExtractGeometry>::New();
        extractor->SetImplicitFunction(planes);
        extractor->SetInputData(dataSet);
        extractor->Update();

        // 通过单元索引获取单元ID。
        const QList<int> cellsIndice = extractor->getSelectOriginalCells();
        if (cellsIndice.isEmpty())
        {
            return;
        }

        Exchange::GraphVTKCommons::ShapePickMode sType = Exchange::GraphVTKCommons::PickNone;

        // 根据拾取数据类型进行不同数据获取。
        switch (m_pickedData->getPickedDataType())
        {
        case  GUI::GUIPickInfo::PickObjType::POBGeoVert:
            sType = Exchange::GraphVTKCommons::ShapePickMode::PickGeoVertex;
            break;
        case  GUI::GUIPickInfo::PickObjType::POBGeoEdge:
            sType = Exchange::GraphVTKCommons::ShapePickMode::PickGeoEdge;
            break;
        case  GUI::GUIPickInfo::PickObjType::POBGeoFace:
            sType = Exchange::GraphVTKCommons::ShapePickMode::PickGeoFace;
            break;
        case  GUI::GUIPickInfo::PickObjType::POBGeoSolid:
            sType = Exchange::GraphVTKCommons::ShapePickMode::PickGeoSolid;
            break;
        case  GUI::GUIPickInfo::PickObjType::POBMeshVert:
            sType = Exchange::GraphVTKCommons::ShapePickMode::PickMeshVertex;
            break;
        case  GUI::GUIPickInfo::PickObjType::POBMeshVertSurf:
            sType = Exchange::GraphVTKCommons::ShapePickMode::PickMeshVertexSurf;
            break;
        case  GUI::GUIPickInfo::PickObjType::POBMeshCell:
            sType = Exchange::GraphVTKCommons::ShapePickMode::PickMeshCell;
            break;
        case  GUI::GUIPickInfo::PickObjType::POBMeshCellSurf: {
            byAreaPickByMeshCellSurf();
            return;
        }
        default:
            return;
        }

        // 被拾取形状编号。
        QVector<int> shapeIds;

        // 预处理拾取单元数据。（加速判断拾取子Id包含关系）
        int nCells = dataSet->GetNumberOfCells();
        QVector<int> cellPickedFlags;
        cellPickedFlags.resize(nCells);
        cellPickedFlags.fill(0);

        // 获取形状数据Id。
        for (const int& index : cellsIndice)
        {
            int id = gobj->getShapeIdByVTKCellId(index, sType);
            if (!shapeIds.contains(id))
            {
                shapeIds.push_back(id);
            }

            cellPickedFlags[index] = 1;
        }

        // 保存拾取数据。
        for (int i = 0; i < shapeIds.count(); i++)
        {
            int& shapeId = shapeIds[i];

            // 检测当前OCC数据是否完全被选中。
            QVector<int> subIds = gobj->getVTKCellIdsByShapeId(shapeId, sType);

            bool isFullPicked = true;
            for (const int& id : subIds)
            {
                isFullPicked &= (cellPickedFlags[id] == 1);
            }

            // 完全选中则视为被框选。
            if (isFullPicked)
            {
                m_pickedData->addPickOtherInfo(PickDataInfo(shapeId));
                int vTopoIndex = gobj->getVirTopoIndexByShapeId(shapeId, sType);
                m_pickedData->appendPickedOtherId(shapeId, vTopoIndex);
            }
        }

        shapeIds.clear();
    }

    void PickedDataCalculator::byAreaPickByMeshCellSurf()
    {
        Exchange::GraphVTKObject3D* gobj = m_pickedData->getPickedGraphObejct();
        vtkPlanes* planes = m_pickedData->getCutPlane();
        vtkActor* actor = m_pickedData->getPickedActor();
        if (!gobj || !planes || !actor) {
            return;
        }

        // 获取拾取数据集。
        vtkDataSet* dataSet = actor->GetMapper()->GetInputAsDataSet();
        if (!dataSet) {
            return;
        }

        vtkSmartPointer<FITKExtractGeometry> extractor = vtkSmartPointer<FITKExtractGeometry>::New();
        extractor->SetImplicitFunction(planes);
        extractor->SetInputData(dataSet);
        extractor->Update();

        // 通过单元索引获取单元ID。
        const QList<int> cellsIndice = extractor->getSelectOriginalCells();
        if (cellsIndice.isEmpty()) {
            return;
        }

        // 获取GraphVTKObjectPartMesh用于访问mesh特征
        Exchange::GraphVTKObjectPartMesh* partMeshObj = dynamic_cast<Exchange::GraphVTKObjectPartMesh*>(gobj);
        if (partMeshObj == nullptr) {
            return;
        }

        // 获取网格特征
        Interface::FITKMeshFeatureVTK* meshFeature = partMeshObj->getMeshFeature();
        if (meshFeature == nullptr) {
            return;
        }

        // 获取表面过滤器
        FITKSurfaceFilter* surfaceFilter = meshFeature->getSurfaceFilter();
        if (surfaceFilter == nullptr) {
            return;
        }

        // 获取原始网格数据
        vtkDataSet* partGrid = partMeshObj->getMesh(Exchange::GraphVTKCommons::ShapePickMode::PickMeshCell);
        if (partGrid == nullptr) {
            return;
        }

        // 获取全局节点数据用于节点ID转换
        Radioss::FITKRadiossCase* caseData = FITKAPP->getGlobalData()->getPhysicsData<Radioss::FITKRadiossCase>();
        if (caseData == nullptr) return;

        Radioss::FITKRadiossMeshModel* meshModel = caseData->getMeshModel();
        if (meshModel == nullptr) return;

        Radioss::FITKRadiossNodes* radiossNodes = meshModel->getNodes();
        if (radiossNodes == nullptr) return;

        Exchange::GraphVTKCommons::ShapePickMode sType = Exchange::GraphVTKCommons::PickMeshCellSurf;

        // 被拾取形状编号集合
        QSet<int> pickedShapeIds;

        // 处理每个被框选的表面单元
        for (const int& surfCellIndex : cellsIndice) {
            // 获取表面单元对应的原始单元ID和面索引
            int cellID = gobj->getShapeIdByVTKCellId(surfCellIndex, sType);
            if (cellID == -1) continue;

            int cellSurfIndex = partMeshObj->getEleSurfIndexByEleSurfCellID(surfCellIndex, sType);

            // 获取表面单元信息
            int orgCellIndex = -1;
            int faceIndex = -1;
            surfaceFilter->getSurfaceCellInfo(surfCellIndex, orgCellIndex, faceIndex);

            // 如果已经处理过这个单元，跳过
            if (pickedShapeIds.contains(cellID)) {
                continue;
            }

            pickedShapeIds.insert(cellID);

            // 添加到拾取ID列表
            m_pickedData->Ids.push_back(cellID);

            // 创建PickDataInfo并添加面索引信息
            PickDataInfo otherInfo;
            otherInfo._id = cellID;
            if (cellSurfIndex != -1) {
                otherInfo._otherInfo.append(cellSurfIndex);
            }
            else if (faceIndex != -1) {
                otherInfo._otherInfo.append(faceIndex);
            }
            m_pickedData->addPickOtherInfo(otherInfo);

            // 获取面节点信息并填充FaceMap和FaceMapInternal
            if (orgCellIndex != -1 && faceIndex != -1) {
                QList<int> face;
                vtkCell* fullCell = partGrid->GetCell(orgCellIndex);
                if (fullCell != nullptr) {
                    vtkCell* faceCell = fullCell->GetFace(faceIndex);
                    vtkIdList* cellPoints = nullptr;

                    if (faceCell) {
                        cellPoints = faceCell->GetPointIds();
                    }
                    else {
                        cellPoints = fullCell->GetPointIds();
                    }

                    if (cellPoints != nullptr) {
                        // 获取面上的所有节点ID
                        for (int i = 0; i < cellPoints->GetNumberOfIds(); i++) {
                            int ptIndex = cellPoints->GetId(i);
                            int ptId = -1;

                            // 通过全局节点管理器获取节点ID
                            if (ptIndex >= 0 && ptIndex < radiossNodes->getNodeCount()) {
                                Core::FITKNode* node = radiossNodes->getNodeAt(ptIndex);
                                if (node != nullptr) {
                                    ptId = node->getNodeID();
                                }
                            }

                            if (ptId == -1) {
                                face.clear();
                                break;
                            }
                            else {
                                face.push_back(ptId);
                            }
                        }

                        // 如果成功获取所有面节点，保存面信息
                        if (!face.isEmpty()) {
                            m_pickedData->FaceMap[cellID].push_back(face);
                            m_pickedData->FaceMapInternal[cellID].push_back(faceIndex);
                        }
                    }
                }
            }
        }

        // 清理重复数据
        pickedShapeIds.clear();
    }
}